#!/bin/bash
# this is the functions file for the network-manager-plugin
#
# openQRM Enterprise developed by openQRM Enterprise GmbH.
#
# All source code and content (c) Copyright 2014, openQRM Enterprise GmbH unless specifically noted otherwise.
#
# This source code is released under the GNU General Public License version 2, unless otherwise agreed with openQRM Enterprise GmbH.
# The latest version of this license can be found here: src/doc/LICENSE.txt
#
# By using this software, you acknowledge having read this license and agree to be bound thereby.
#
#           http://openqrm-enterprise.com
#
# Copyright 2014, openQRM Enterprise GmbH <info@openqrm-enterprise.com>
#
INTERFACES="/etc/network/interfaces"
NETWORK_CONFIG_DIR_RH="/etc/sysconfig/network-scripts/"
NETWORK_CONFIG_DIR_SUSE="/etc/sysconfig/network/"


################ common network-manager functions

# logs for network-manager
function network_manager_log() {
	local COMPONENT=$1
	shift
	local MESSAGE=$@
	logger -i -t "network-manager plug-in" "$COMPONENT : $MESSAGE"
}


################ network-manager functions



function get_ip_list_for_dev() {
	NW_DEV=$1
	NET_DEV_IP_LIST=""
	DEV_LOOP=0
	for NET_DEV_IP in `ip addr show $NW_DEV | grep -w inet | awk '{ print $2 }'`; do
		NET_DEV_IP=`echo $NET_DEV_IP | cut -d'/' -f1`
		NET_DEV_IP_CONFIG=""
		if [ "$NET_DEV_IP" != "" ]; then
			NET_DEV_BROADCAST=`ifconfig $NW_DEV | grep -w $NET_DEV_IP | awk '{ print $3 }' | cut -d':' -f2`
			NET_DEV_SUBNETMASK=`ifconfig $NW_DEV | grep -w $NET_DEV_IP | awk '{ print $4 }' | cut -d':' -f2`
			NET_DEV_IP_CONFIG="$NET_DEV_IP/$NET_DEV_BROADCAST/$NET_DEV_SUBNETMASK"
		fi
		if [ "$DEV_LOOP" == "0" ]; then
			NET_DEV_IP_LIST="$NET_DEV_IP_CONFIG"
		else
			NET_DEV_IP_LIST="$NET_DEV_IP_LIST:$NET_DEV_IP_CONFIG"
		fi
		DEV_LOOP=$(( $DEV_LOOP + 1 ))
	done
	echo $NET_DEV_IP_LIST
}


function get_network_address() {
	local NIP=$1
	local NSUB=$2
	IFS=. read -r i1 i2 i3 i4 <<< "$NIP"
	IFS=. read -r m1 m2 m3 m4 <<< "$NSUB"
	printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$(($i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
}



function openqrm_remove_network_interface_debian() {
	local INTERFACE_NAME=$1
	INTERFACE_NAME_SEQ=""
	echo "# generated by the openQRM network-manager plugin" > $INTERFACES.new1
	echo >> $INTERFACES.new1
	while read line; do
		if echo $line | grep ^# >/dev/null; then
			continue
		fi
		if echo $line | grep -w ^auto >/dev/null; then
			continue
		fi
		if echo $line | grep -w ^iface >/dev/null; then
			INTERFACE_NAME_SEQ=`echo $line | grep ^iface | awk '{ print $2 }'`
			if [ "$INTERFACE_NAME_SEQ" != "$INTERFACE_NAME" ]; then
				if grep -w $INTERFACE_NAME_SEQ $INTERFACES | grep -w ^auto >/dev/null; then
					echo "auto $INTERFACE_NAME_SEQ" >> $INTERFACES.new1
				fi
				echo "$line" >> $INTERFACES.new1
			fi
		else
			if [ "$INTERFACE_NAME_SEQ" != "" ] && [ "$INTERFACE_NAME_SEQ" != "$INTERFACE_NAME" ]; then
				echo "	$line" >> $INTERFACES.new1
			fi
		fi
		if [ "$line" == "" ] && [ "$INTERFACE_NAME_SEQ" != "" ]; then
			# config for IFACE ends here, write it
			INTERFACE_NAME_SEQ=""
			echo "" >> $INTERFACES.new1
		fi
	done < $INTERFACES
	echo "" >> $INTERFACES.new1
	mv -f $INTERFACES.new1 $INTERFACES

}


function openqrm_remove_network_interface_rh() {
	local INTERFACE_NAME=$1
	rm -f $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
}




# add a interface
function openqrm_add_interface() {
	local NETWORKCONFIG=$1
	if [ -f /etc/debian_version ]; then
		openqrm_add_interface_debian $NETWORKCONFIG
	elif [ -f /etc/redhat-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_RH
		openqrm_add_interface_rh $NETWORKCONFIG
	elif [ -f /etc/SuSE-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_SUSE
		openqrm_add_interface_rh $NETWORKCONFIG
	fi
}


# removes a bridge
function openqrm_remove_interface() {
	local NETWORKCONFIG=$1
	if [ -f /etc/debian_version ]; then
		openqrm_remove_interface_debian $NETWORKCONFIG
	elif [ -f /etc/redhat-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_RH
		openqrm_remove_interface_rh $NETWORKCONFIG
	elif [ -f /etc/SuSE-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_SUSE
		openqrm_remove_interface_rh $NETWORKCONFIG
	fi
}



# saves the lastgood network configuration
function openqrm_save_network_config() {
	if [ -f /etc/debian_version ]; then
		cp -f $INTERFACES $INTERFACES.rollback
		return
	fi
	if [ -f /etc/redhat-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_RH
	elif [ -f /etc/SuSE-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_SUSE
	fi
	mkdir -p $NETWORK_CONFIG_DIR/rollback
	rm -f 	$NETWORK_CONFIG_DIR/rollback/*
	cp -af $NETWORK_CONFIG_DIR/ifcfg* $NETWORK_CONFIG_DIR/rollback/
}



# rolls back the lastgood network configuration
function openqrm_rollback_network_config() {
	if [ -f /etc/debian_version ]; then
		cp -f $INTERFACES.rollback $INTERFACES
		return
	fi
	if [ -f /etc/redhat-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_RH
	elif [ -f /etc/SuSE-release ]; then
		export NETWORK_CONFIG_DIR=$NETWORK_CONFIG_DIR_SUSE
	fi
	cp -f $NETWORK_CONFIG_DIR/rollback/ifcfg* $NETWORK_CONFIG_DIR/
}






function openqrm_remove_interface_debian() {
	local NETWORKCONFIG=$1
	local INTERFACE_TYPE=`echo $NETWORKCONFIG | cut -d'@' -f1`
	local INTERFACE_NAME=`echo $NETWORKCONFIG | cut -d'@' -f2`
	local BRIDGE_NETWORK=`echo $NETWORKCONFIG | cut -d'@' -f3`
	# backup + rollback
	NOW=`date +%T%x | sed -e "s/://g" | sed -e "s#/##g"`
	cp -f $INTERFACES $INTERFACES.$NOW

	if [ "$INTERFACE_TYPE" == "bridge" ]; then
		if [ "$BRIDGE_NETWORK" == "" ]; then
			BRIDGE_NETWORK=`brctl show | tail -n+2 | grep -w $INTERFACE_NAME | awk '{ print $4 }'`
		fi
		if [ "$BRIDGE_NETWORK" != "" ]; then
			openqrm_remove_network_interface_debian $BRIDGE_NETWORK
		fi
	fi
	openqrm_remove_network_interface_debian $INTERFACE_NAME

}




function openqrm_remove_interface_rh() {
	local NETWORKCONFIG=$1
	local INTERFACE_TYPE=`echo $NETWORKCONFIG | cut -d'@' -f1`
	local INTERFACE_NAME=`echo $NETWORKCONFIG | cut -d'@' -f2`
	local BRIDGE_NETWORK=`echo $NETWORKCONFIG | cut -d'@' -f3`
	# backup
	NOW=`date +%T%x | sed -e "s/://g" | sed -e "s#/##g"`
	mkdir -p $NETWORK_CONFIG_DIR/backup/$NOW
	cp -af $NETWORK_CONFIG_DIR/ifcfg* $NETWORK_CONFIG_DIR/backup/$NOW/

	if [ "$INTERFACE_TYPE" == "bridge" ]; then
		if [ "$BRIDGE_NETWORK" == "" ]; then
			BRIDGE_NETWORK=`brctl show | tail -n+2 | grep -w $INTERFACE_NAME | awk '{ print $4 }'`
		fi
		if [ "$BRIDGE_NETWORK" != "" ]; then
			openqrm_remove_network_interface_rh $BRIDGE_NETWORK
		fi
	fi
	openqrm_remove_network_interface_rh $INTERFACE_NAME

}



function openqrm_add_interface_debian() {
	local NETWORKCONFIG=$1
	local INTERFACE_TYPE=`echo $NETWORKCONFIG | cut -d'@' -f1`
	local INTERFACE_NAME=`echo $NETWORKCONFIG | cut -d'@' -f2`
	local BRIDGE_NETWORK=`echo $NETWORKCONFIG | cut -d'@' -f3`
	local BRIDGE_FD=`echo $NETWORKCONFIG | cut -d'@' -f4`
	local BRIDGE_HELLO=`echo $NETWORKCONFIG | cut -d'@' -f5`
	local BRIDGE_MAXAGE=`echo $NETWORKCONFIG | cut -d'@' -f6`
	local BRIDGE_STP=`echo $NETWORKCONFIG | cut -d'@' -f7`
	local BRIDGE_MAC=`echo $NETWORKCONFIG | cut -d'@' -f8`
	local INTERFACE_IP_ADDRESS=`echo $NETWORKCONFIG | cut -d'@' -f9`
	local INTERFACE_SUBNETMASK=`echo $NETWORKCONFIG | cut -d'@' -f10`
	local INTERFACE_GATEWAY=`echo $NETWORKCONFIG | cut -d'@' -f11`
	local BRIDGE_VLAN=`echo $NETWORKCONFIG | cut -d'@' -f12`
	# backup
	NOW=`date +%T%x | sed -e "s/://g" | sed -e "s#/##g"`
	cp -f $INTERFACES $INTERFACES.$NOW

	if [ "$INTERFACE_TYPE" == "bridge" ]; then
		if [ "$BRIDGE_NETWORK" == "" ]; then
			BRIDGE_NETWORK=`brctl show | tail -n+2 | grep -w $INTERFACE_NAME | awk '{ print $4 }'`
		fi
		if [ "$BRIDGE_NETWORK" != "" ]; then
			openqrm_remove_network_interface_debian $BRIDGE_NETWORK
		fi
		openqrm_remove_network_interface_debian $INTERFACE_NAME

		# add new config
		if [ "$BRIDGE_NETWORK" != "" ]; then
			if [ "$BRIDGE_VLAN" != "" ]; then
				echo "iface $BRIDGE_NETWORK.$BRIDGE_VLAN inet manual" >> $INTERFACES
				echo "	vlan-raw-device $BRIDGE_NETWORK" >> $INTERFACES
			else
				echo "iface $BRIDGE_NETWORK inet manual" >> $INTERFACES
			fi
			echo "" >> $INTERFACES
			NETWORK_CARD_MAC=`ifconfig $BRIDGE_NETWORK | grep HWaddr | awk '{ print $5 }'`
		fi
		# bridge settings
		echo "auto $INTERFACE_NAME" >> $INTERFACES
		echo "iface $INTERFACE_NAME inet static" >> $INTERFACES
		if [ "$INTERFACE_IP_ADDRESS" != "" ]; then
			echo "	address $INTERFACE_IP_ADDRESS" >> $INTERFACES
		fi
		if [ "$INTERFACE_SUBNETMASK" != "" ]; then
			echo "	netmask $INTERFACE_SUBNETMASK" >> $INTERFACES
		fi
		if [ "$INTERFACE_GATEWAY" != "" ]; then
			echo "	gateway $INTERFACE_GATEWAY" >> $INTERFACES
		fi
		if [ "$BRIDGE_FD" != "" ]; then
			echo "	bridge_fd $BRIDGE_FD" >> $INTERFACES
		fi
		if [ "$BRIDGE_HELLO" != "" ]; then
			echo "	bridge_hello $BRIDGE_HELLO" >> $INTERFACES
		fi
		if [ "$BRIDGE_MAXAGE" != "" ]; then
			echo "	bridge_maxage $BRIDGE_MAXAGE" >> $INTERFACES
		fi
		if [ "$BRIDGE_STP" != "" ]; then
			if [ "$BRIDGE_STP" == "0" ]; then
				STP="off"
			else
				STP="on"
			fi
			echo "	bridge_stp $STP" >> $INTERFACES
		fi
		# attach nic
		if [ "$BRIDGE_NETWORK" != "" ]; then
			if [ "$BRIDGE_VLAN" != "" ]; then
				echo "	bridge_ports $BRIDGE_NETWORK.$BRIDGE_VLAN" >> $INTERFACES
			else
				echo "	bridge_ports $BRIDGE_NETWORK" >> $INTERFACES
			fi
		fi
		if [ "$BRIDGE_MAC" != "" ]; then
			if [ "$BRIDGE_MAC" == "1" ] && [ "$NETWORK_CARD_MAC" != "" ]; then
				echo "	post-up ip link set $INTERFACE_NAME address $NETWORK_CARD_MAC" >> $INTERFACES
			fi
		fi

	else
		echo "auto $INTERFACE_NAME" >> $INTERFACES
		echo "iface $INTERFACE_NAME inet static" >> $INTERFACES
		if [ "$INTERFACE_IP_ADDRESS" != "" ]; then
			echo "	address $INTERFACE_IP_ADDRESS" >> $INTERFACES
		fi
		if [ "$INTERFACE_SUBNETMASK" != "" ]; then
			echo "	netmask $INTERFACE_SUBNETMASK" >> $INTERFACES
		fi
		if [ "$INTERFACE_GATEWAY" != "" ]; then
			echo "	gateway $INTERFACE_GATEWAY" >> $INTERFACES
		fi
	fi
	echo "" >> $INTERFACES


}




function openqrm_add_interface_rh() {
	local NETWORKCONFIG=$1
	local INTERFACE_TYPE=`echo $NETWORKCONFIG | cut -d'@' -f1`
	local INTERFACE_NAME=`echo $NETWORKCONFIG | cut -d'@' -f2`
	local BRIDGE_NETWORK=`echo $NETWORKCONFIG | cut -d'@' -f3`
	local BRIDGE_FD=`echo $NETWORKCONFIG | cut -d'@' -f4`
	local BRIDGE_HELLO=`echo $NETWORKCONFIG | cut -d'@' -f5`
	local BRIDGE_MAXAGE=`echo $NETWORKCONFIG | cut -d'@' -f6`
	local BRIDGE_STP=`echo $NETWORKCONFIG | cut -d'@' -f7`
	local BRIDGE_MAC=`echo $NETWORKCONFIG | cut -d'@' -f8`
	local INTERFACE_IP_ADDRESS=`echo $NETWORKCONFIG | cut -d'@' -f9`
	local INTERFACE_SUBNETMASK=`echo $NETWORKCONFIG | cut -d'@' -f10`
	local INTERFACE_GATEWAY=`echo $NETWORKCONFIG | cut -d'@' -f11`
	local BRIDGE_VLAN=`echo $NETWORKCONFIG | cut -d'@' -f12`

	# backup
	NOW=`date +%T%x | sed -e "s/://g" | sed -e "s#/##g"`
	mkdir -p $NETWORK_CONFIG_DIR/backup/$NOW
	cp -af $NETWORK_CONFIG_DIR/ifcfg* $NETWORK_CONFIG_DIR/backup/$NOW/

	if [ "$INTERFACE_TYPE" == "bridge" ]; then
		# bridge with nic attached1
		if [ "$BRIDGE_NETWORK" != "" ]; then
			NETWORK_CARD_MAC=`ifconfig $NETWORK_CARD | grep HWaddr | awk '{ print $5 }'`
			if [ "$BRIDGE_VLAN" != "" ]; then
				echo "# VLAN Interface for bridge $INTERFACE_NAME" > $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "DEVICE=$BRIDGE_NETWORK.$BRIDGE_VLAN" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				if [ "$NETWORK_CARD_MAC" != "" ]; then
					echo "HWADDR=$NETWORK_CARD_MAC" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				fi
				echo "ONBOOT=yes" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "HOTPLUG=no" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "BOOTPROTO=none" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "TYPE=Ethernet" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "VLAN=yes" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "BRIDGE=$INTERFACE_NAME" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
			else
				echo "# Interface for bridge $INTERFACE_NAME" > $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "DEVICE=$BRIDGE_NETWORK" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				if [ "$NETWORK_CARD_MAC" != "" ]; then
					echo "HWADDR=$NETWORK_CARD_MAC" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				fi
				echo "ONBOOT=yes" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "TYPE=Ethernet" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "IPV6INIT=no" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "USERCTL=no" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
				echo "BRIDGE=$INTERFACE_NAME" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
			fi
			echo "" >> $NETWORK_CONFIG_DIR/ifcfg-$BRIDGE_NETWORK
		fi
		# bridge settings
		echo "DEVICE=$INTERFACE_NAME" > $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		echo "BOOTPROTO=static" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		echo "ONBOOT=yes" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		echo "TYPE=Bridge" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		if [ "$INTERFACE_IP_ADDRESS" != "" ]; then
			echo "IPADDR=$INTERFACE_IP_ADDRESS" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
		if [ "$INTERFACE_SUBNETMASK" != "" ]; then
			echo "NETMASK=$INTERFACE_SUBNETMASK" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
		if [ "$INTERFACE_GATEWAY" != "" ]; then
			echo "GATEWAY=$INTERFACE_GATEWAY" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
	#		if [ "$BRIDGE_MAC" != "" ]; then
	#			if [ "$BRIDGE_MAC" == "1" ] && [ "$NETWORK_CARD_MAC" != "" ]; then
	#				echo "" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
	#			fi
	#		fi
		if [ "$BRIDGE_FD" != "" ]; then
			echo "DELAY=$BRIDGE_FD" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
		if [ "$BRIDGE_HELLO" != "" ]; then
			echo "HELLO=$BRIDGE_HELLO" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
		if [ "$BRIDGE_MAXAGE" != "" ]; then
			echo "MAXAGE=$BRIDGE_MAXAGE" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
		if [ "$BRIDGE_STP" != "" ]; then
			if [ "$BRIDGE_STP" == "0" ]; then
				STP="no"
			else
				STP="yes"
			fi
			echo "STP=$STP" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
	else
		# regular nic
		echo "DEVICE=$INTERFACE_NAME" > $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		echo "BOOTPROTO=static" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		echo "ONBOOT=yes" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		if [ "$INTERFACE_IP_ADDRESS" != "" ]; then
			echo "IPADDR=$INTERFACE_IP_ADDRESS" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
		if [ "$INTERFACE_SUBNETMASK" != "" ]; then
			echo "NETMASK=$INTERFACE_SUBNETMASK" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
		if [ "$INTERFACE_GATEWAY" != "" ]; then
			echo "GATEWAY=$INTERFACE_GATEWAY" >> $NETWORK_CONFIG_DIR/ifcfg-$INTERFACE_NAME
		fi
	fi
}








